#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"
#include "Daemon.hpp"
#include <memory> // smart_ptr

// #define PRE_COMPILE_DEBUG 1

using namespace LogModule;
using cal_fun = std::function<Response(const Request&rq)>;


class Parse
{
public:
    Parse(cal_fun cal)
    : _cal(cal)
    {}
    // package 确保有完整的报文
    // 不完整 继续读，完整 提取 反序列化 Request 计算模块处理
    std::string Entry(std::string &package)
    {
        std::string msg;
        std::string resp_str;
        while (Decode(package, &msg))
        {
            LOG(LogLevel::INFO) << "\n" << msg;
            if (msg.empty())
            {
                break; // 回到调用函数 执行 continue继续读取
            }
            // msg 为 content
            Request rq;
            if (!rq.Deserialize(msg)) // 可能格式有问题
            {
                break;
            }
            std::cout << "################" << std::endl;
            rq.Print();
            std::cout << "################" << std::endl;
            // 计算
            Response resp = _cal(rq);

            // 序列化
            std::string str;
            resp.Serialize(str);
            LOG(LogLevel::DEBUG) << "序列化 ：\n" << str;
            // Encode
            Encode(str);
            LOG(LogLevel::DEBUG) << "Encode ：\n" << str;
            
            // 拼接应答
            resp_str += str;
        }
        LOG(LogLevel::DEBUG) << "respstr ：\n" << resp_str;

        return resp_str;
    }
private:
    cal_fun _cal;
};

int main()
{
#ifdef PRE_COMPILE_DEBUG
    // DEBUG
    LOG_CONSOLE;
    // 向文件写入日志
#else
    LOG_FILE;
    Daemon(false,false);
#endif
    //  代码三层结构
    // 1. 计算模块  用户层
    Calculator mycal;
    // 2. 解析模块  传输层
    Parse myparse([&mycal](const Request &rq){
        return mycal.Calculate(rq);
    });
    // 3. 通信模块  网络层
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&myparse](std::string &package){
        return myparse.Entry(package);
    });

    tsvr->InitServer();

    tsvr->Start();

    return 0;
}